package com.zs.juc.thread;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author madison
 * @description
 * @date 2022/8/21 11:00
 */
public class ThreadPoolBlockQueueDemoTest {
    public static void main(String[] args) throws InterruptedException {
        // new SynchronousQueue<Runnable>() 队列消费完才产生另一个
        // 结果就是线程N 做第N个项目
//        ExecutorService executorService = Executors.newCachedThreadPool(); //快

        // LinkedBlockingQueue MAX容量队列
//        ExecutorService executorService = Executors.newFixedThreadPool(10);// 慢

        // 咋一瞅，不就是newFixedThreadPool(1)吗？定眼一看，这里多了一层FinalizableDelegatedExecutorService包装
        // FixedThreadPool可以向下转型为ThreadPoolExecutor，并对其线程池进行配置，
        // 而SingleThreadExecutor被包装后，无法成功向下转型。因此，SingleThreadExecutor被定以后，无法修改，做到了真正的Single。
//        ExecutorService executorService = Executors.newSingleThreadExecutor();//最慢

        int workerQueueSize = 65536;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(workerQueueSize);
        int coreSize = 16;
        int maxSize = 24;
        int availableProcessorsSize = Runtime.getRuntime().availableProcessors() * 2;
        if (availableProcessorsSize > maxSize) {
            System.out.println("Setting worker pool size to " + availableProcessorsSize + " based on available processors * 2");
            maxSize = availableProcessorsSize;
        }
        int aliveTime = 60;

        // 1-10 -> 11-20 -> 21-30 执行结果是 1-10 -> 21-30 -> 11-20
        // 原因是提交优先级和执行优先级不一样：
        // 提交优先级： 核心线程-> 线程等待队列  -> 非核心线程
        // 执行优先级： 核心线程-> 非核心线程    -> 线程等待队列
        ExecutorService executorService = new ThreadPoolExecutor(coreSize, maxSize,
                aliveTime, TimeUnit.SECONDS,
                workQueue, new WorkerThreadFactory());

        int  produceTaskMaxNumber = 70000;      //总线程数
        for (int i = 1; i <= produceTaskMaxNumber; i++) {
            executorService.execute(new MyTask(i));
        }
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.MINUTES);
    }

    private static class MyTask implements Runnable {

        int i;

        public MyTask(int i) {
            this.i = i;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + "做第" + i + "个项目");
            try {
                // newCachedThreadPool 不sleep 线程会复用
//                TimeUnit.SECONDS.sleep(1); //业务逻辑
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    static class WorkerThreadFactory implements ThreadFactory {
        private final ThreadGroup workerGroup = new ThreadGroup("MoquiWorkers");
        private final AtomicInteger threadNumber = new AtomicInteger(1);

        public Thread newThread(Runnable r) {
            return new Thread(workerGroup, r, "MoquiWorker-" + threadNumber.getAndIncrement());
        }
    }
}

